package com.yydream.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yydream.common.constant.RedisKeyEnums;
import com.yydream.common.utils.PageUtils;
import com.yydream.common.utils.R;
import com.yydream.common.utils.RedisCache;
import com.yydream.dto.SysAdministrativeAreaDTO;
import com.yydream.entity.SysAdministrativeAreaEntity;
import com.yydream.mapper.SysAdministrativeAreaMapper;
import com.yydream.service.SysAdministrativeAreaService;
import com.yydream.vo.SysAdministrativeAreaVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysAdministrativeAreaServiceImpl extends ServiceImpl<SysAdministrativeAreaMapper, SysAdministrativeAreaEntity> implements SysAdministrativeAreaService{

    @Autowired
    private RedisCache redisCache;

    @Override
    public R areasData(SysAdministrativeAreaDTO req) {
        List<SysAdministrativeAreaEntity> cacheList = redisCache.getCacheList(RedisKeyEnums.ADMINISTRATIVE_AREA.getKey());
        if (CollectionUtil.isEmpty(cacheList)) {
//            如果缓存中没有，那就从数据库中查询,并且存入缓存中
            cacheList = this.list();
            if (CollectionUtil.isNotEmpty(cacheList)) {
                redisCache.setCacheList(RedisKeyEnums.ADMINISTRATIVE_AREA.getKey(), cacheList);
            }
        }
        if (CollectionUtil.isNotEmpty(cacheList)) {
            if (StringUtils.isAllEmpty(req.getName(), req.getCode(), req.getZip(), req.getTel(), req.getParentcode())) {
                return R.ok().put( null);
            }
            LambdaQueryWrapper<SysAdministrativeAreaEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(StringUtils.isNotEmpty(req.getName()), SysAdministrativeAreaEntity::getName, req.getName());
            queryWrapper.eq(StringUtils.isNotEmpty(req.getCode()), SysAdministrativeAreaEntity::getCode, req.getCode());
            queryWrapper.eq(StringUtils.isNotEmpty(req.getZip()), SysAdministrativeAreaEntity::getZip, req.getZip());
            queryWrapper.eq(StringUtils.isNotEmpty(req.getTel()), SysAdministrativeAreaEntity::getTel, req.getTel());
            queryWrapper.eq(StringUtils.isNotEmpty(req.getParentcode()), SysAdministrativeAreaEntity::getParentcode, req.getParentcode());
            List<SysAdministrativeAreaEntity> list = this.list(queryWrapper);
            List<SysAdministrativeAreaVo> sysAdministrativeAreaVos = PageUtils.toList(list, SysAdministrativeAreaVo.class);
            int maxLevel = !Objects.isNull(req.getChildren()) ? req.getChildren() : 0;
            List<SysAdministrativeAreaEntity> finalCacheList = cacheList;
            sysAdministrativeAreaVos.forEach(p -> {
                String parentcodes = p.getParentcodes();
                Integer level = p.getLevel();
                Long id = p.getId();
                List<SysAdministrativeAreaEntity> collect = finalCacheList.stream().filter(c -> {
                    boolean contains = c.getParentcodes().contains(parentcodes);
                    boolean hasLevel = c.getLevel() <= (level + maxLevel);
                    boolean b = id != c.getId();
                    return contains && b && hasLevel;
                }).collect(Collectors.toList());
                List<SysAdministrativeAreaVo> areaVos = PageUtils.toList(collect, SysAdministrativeAreaVo.class);
                loopAdministrativeArea(p, areaVos);
            });
            return R.ok().put( sysAdministrativeAreaVos);
        }
        return R.ok().put( null);
    }

    public void loopAdministrativeArea(SysAdministrativeAreaVo c, List<SysAdministrativeAreaVo> allList) {
        if (Objects.nonNull(c)) {
            List<SysAdministrativeAreaVo> childList = allList.stream().filter(d -> c.getCode().equals(d.getParentcode())).collect(Collectors.toList());
            c.setChildren(childList.size() != 0 ? childList : null);
            if (!CollectionUtil.isEmpty(childList)) {
                childList.forEach(d -> {
                    loopAdministrativeArea(d, allList);
                });
            }
        }
    }
}
